package com.jushu.storbox.filesystem;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Arrays;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.jushu.storbox.R;
import com.jushu.storbox.ShowImageActivity;
import com.jushu.storbox.ViewActivity;
import com.jushu.storbox.constant.ClientConfig;
import com.jushu.storbox.constant.Constant;
import com.jushu.storbox.util.DirectoryUtil;
import com.jushu.storbox.util.LogUtil;
import com.jushu.storbox.util.PublicTools;
import com.huawei.sharedrive.sdk.android.modelV2.response.FileInfoResponseV2;

/**
 * 
 * Local file manage impl
 * 
 */
public class LocalFileManageImpl implements iFileManager
{
    
    private Context context;
    
    private String TAG = "IDeskMDMTools";
        
    public LocalFileManageImpl(Context context)
    {
        this.context = context;
    }        
    
    /**
     * clear cache
     * @return 
     */
    @Override
    public boolean clearCloudDriveCache()
    {
        LogUtil.i(TAG, "clearLocalCache");
        try
        {
            String folderPath = DirectoryUtil.generateOwnerDir(context);
            File file = new File(folderPath);
            if (file.exists())
            {
                LogUtil.i(TAG, "file Is  exist!");
                return delete(folderPath);
            }
            else
            {
                LogUtil.i(TAG, "file Is NOT exist!");
                return true;
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * @param fileName
     * @return
     */
    private boolean delete(String fileName)
    {
        File file = new File(fileName);
        if (!file.exists())
        {
            LogUtil.i(TAG, "file isn't  exist!");
            return true;
        }
        else
        {
            if (file.isFile())
            {
                return deleteFile(fileName);
            }
            else
            {
                return deleteDirectory(fileName);
            }
        }
    }
    
    /**
     * @param fileName
     * @return
     */
    @Override
    public boolean deleteFile(String fileName)
    {
        File file = new File(fileName);
        if (file.isFile() && file.exists())
        {
            file.delete();
            LogUtil.i(TAG, "delete file successed!");
            return true;
        }
        else
        {
            LogUtil.i(TAG, "delete file failed!");
            return false;
        }
    }
    
    /**
     * @param dir
     * @return
     */
    public boolean deleteDirectory(String dir)
    {
        if (!dir.endsWith(File.separator))
        {
            dir = dir + File.separator;
        }
        File dirFile = new File(dir);
        if (!dirFile.exists() || !dirFile.isDirectory())
        {
            LogUtil.i(TAG, "delete directory failed!");
            return false;
        }
        boolean flag = true;
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++)
        {
            // delete sub file
            if (files[i].isFile())
            {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                {
                    break;
                }
            }
            // delete sub folder
            else
            {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                {
                    break;
                }
            }
        }
        
        if (!flag)
        {
            LogUtil.i(TAG, "delete directory failed!");
            return false;
        }
        
        // delte current folder
        if (dirFile.delete())
        {
            LogUtil.i(TAG, "delete directory successed!");
            return true;
        }
        else
        {
            LogUtil.i(TAG, "delete directory failed!");
            return false;
        }
    }
    
    /**
     * create parent folder
     * 
     * @param absoluteFile String
     * @return
     */
    @Override
    public void createAbsoluteFilePath(String absoluteFile)
    {
        LogUtil.i(TAG, "createAbsoluteFilePath");
        try
        {
            
            File file = new File(absoluteFile);
            File parentFolder = file.getParentFile();
            if (!parentFolder.exists())
            {
                parentFolder.mkdirs();
                LogUtil.i(TAG, "creat dir successed!");
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    
    /**
     * crate folder
     * 
     * @param path String
     * @return IFile
     */
    @Override
    public void createFilePath(String path)
    {
        {
            LogUtil.i(TAG, "createFilePath");
            try
            {
                File dir = new File(path);
                if (!dir.exists())
                {
                    dir.mkdirs();
                    LogUtil.i(TAG, "creat dir successed!");
                }
            }
            catch (Exception e)
            {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 
     * @param filePath
     * @return
     */
    @Override
    public InputStream encryptFileToInputStream(String filePath)
    {
        InputStream is = null;
        try
        {
            File file = new File(filePath);
            if (file.exists())
            {
                is = new FileInputStream(filePath);
            }
            else
            {
                LogUtil.e(TAG, "encryptFileToInputStream file is not exists...");
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            LogUtil.e(TAG, "encryptFileToInputStream Exception:" + e.getLocalizedMessage());
            e.printStackTrace();
        }
        
        return is;
    }
    
    /**
     * @param filePath String
     * @return boolean
     */
    @Override
    public boolean fileIsExist(String filePath)
    {
        File file = new File(filePath);
        return file.exists();
    }
    
    /**
     * @param fileName
     *            String
     */
    @Override
    public boolean isWPSType(String filePath) {
        boolean isMDMWPS = false;
        try
        {
            String[] MDMWPS = concatAll(Constant.EXCEL_TYPE,
                Constant.PDF_TYPE,
                Constant.WORD_TYPE,
                Constant.PPT_TYPE,
                Constant.TXT_TYPE);
            if (PublicTools.isFileType(filePath, MDMWPS))
            {//
                isMDMWPS = true;
            }
            else
            {
                isMDMWPS = false;
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            isMDMWPS = false;
        }
        return isMDMWPS;
    }
    
    /**
     * @param T[] T[]
     */
    private <T> T[] concatAll(T[] first, T[]... rest)
    {
        int totalLength = first.length;
        for (T[] array : rest)
        {
            totalLength += array.length;
        }
        T[] result = Arrays.copyOf(first, totalLength);
        int offset = first.length;
        for (T[] array : rest)
        {
            System.arraycopy(array, 0, result, offset, array.length);
            offset += array.length;
        }
        return result;
    }
    
    /**
     * get Folder Name in device
     * 
     * @param folderPath String
     * @return double
     */
    @Override
    public String getFileName(String filePath)
    {
        LogUtil.i(TAG, "getFileNameMDM");
        String name = "";
        try
        {
            File f = new File(filePath);
            if (f.exists())
            {
                name = f.getName();
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
            name = "";
        }
        return name;
    }
    
    public String getParentPath(String filePath) {

        LogUtil.i(TAG, "getFileNameMDM");
        String fatherPath = "";
        try
        {
            File f = new File(filePath);
            fatherPath = f.getParent();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            fatherPath = "";
        }
        return fatherPath;
    
    }
    
    /**
     * get Folder Size in device
     * 
     * @param folderPath String
     * @return double
     */
    @Override
    public double getFileSize(String filePath)
    {
        LogUtil.i(TAG, "getFileSizeMDM");
        double size = 0;
        try
        {
            File f = new File(filePath);
            if (f.exists())
            {
                size = f.length();
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
            size = 0;
        }
        return size;
    }
    
    /**
     * get cloudDrive Size in device
     * 
     * @return
     */
    @Override
    public double getCloudDriveSize()
    {
        LogUtil.i(TAG, "getCloudDriveSizeMDM");
        String cloudDrivePath = DirectoryUtil.generateOwnerDir(context);
        return getFolderSizeMDM(cloudDrivePath);
    }
    
    /**
     * get Folder Size in device
     * 
     * @param folderPath String
     * @return double
     */
    private double getFolderSizeMDM(String folderPath)
    {
        double size = 0;
        try
        {
            File f = new File(folderPath);
            if (f.exists())
            {
                File flist[] = f.listFiles();
                if (null != flist)
                {
                    for (int i = 0; i < flist.length; i++)
                    {
                        if (flist[i].isDirectory())
                        {
                            size = size + getFolderSizeMDM(flist[i].getAbsolutePath());
                        }
                        else
                        {
                            size = size + flist[i].length();
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
            size = 0;
        }
        return size;
    }
    
    /**
     * @param fileName String
     */
    @Override
    public void openFile(String filePath, long fileSize)
    {
        LogUtil.i(TAG, "mdmOpenFile");
        LogUtil.i(TAG, "mdmOpenFile");
        Intent intent = new Intent(context, ViewActivity.class);
        intent.putExtra("view_mdm_path", filePath);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
    
    /**
     * go to ScanPictureActivity open img
     */
    private void toScanPictureActivity(String path, long fileSize)
    {
        LogUtil.i(TAG, "toScanPictureActivity");
        if (ClientConfig.PICTURESIZELIMIT <= fileSize)
        {
            Toast.makeText(context, context.getString(R.string.picture_limit), Toast.LENGTH_SHORT).show();
        }
        else
        {
            Intent intent = new Intent();
            Bundle bundle = new Bundle();
            intent.putExtra("scanpicture", bundle);
            bundle.putString("path", path);
            intent.setClass(context, ShowImageActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    }
    
    /**
     * @param encryptedPath
     * @param decryptedPath
     */
    @Override
    public void decryptedFile(String encryptedPath, String decryptedPath)
    {
        FileInputStream fi = null;
        FileOutputStream fo = null;
        FileChannel in = null;
        FileChannel out = null;
        
        try
        {
            fi = new FileInputStream(encryptedPath);
            fo = new FileOutputStream(decryptedPath);
            in = fi.getChannel();
            out = fo.getChannel();
            in.transferTo(0, in.size(), out);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                fi.close();
                in.close();
                fo.close();
                out.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
                
            }
            
        }
    }
    
    /**
     * @param name 
     * @return 
     */
    @Override
    public FileInfoResponseV2 getFileInfo(String id, String folderID, String path)
    {
        
        FileInfoResponseV2 fileInfoResponse = null;
        File file = new File(path);
        if (file.exists())
        {
            FileInfoResponseV2 fileInfoResponse2 = new FileInfoResponseV2();
            if (null != id)
            {
                fileInfoResponse2.setId(id);
                fileInfoResponse2.setName(file.getName());
                fileInfoResponse2.setSize(file.length());
                fileInfoResponse2.setParent(folderID);
                fileInfoResponse2.setModifiedAt(PublicTools.getCurrentTime());
            }
        }
        return fileInfoResponse;
    }
    
    /**
     * get Folder Size in device
     * 
     * @param folderPath String
     * @return double
     */
    @Override
    public String getParentFolderName(String filePath)
    {
        LogUtil.i(TAG, "getFileNameMDM");
        String name = "";
        try
        {
            File f = new File(filePath);
            if (fileIsExist(filePath))
            {
                name = f.getParentFile().getName();
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
            name = "";
        }
        return name;
    }
    
    /**
     * @param oldFilePath
     * @param newFilePath
     * @return
     */
    @Override
    public boolean rename(String oldFilePath ,String newFilePath) {
        LogUtil.i(TAG, "renameMDM");
        try {
            File file = new File(oldFilePath);
            if (file.isFile() && file.exists()) {
                boolean success = file.renameTo(new File(newFilePath));
                LogUtil.i(TAG, "[" + file.getAbsolutePath() + " rename:"
                        + success);
                return true;
            }
            return false;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return false;
        }
    }
}
